//
//  NetworkReq.swift
//  YS
//
//  Created by 元穗 on 2017/5/19.
//  Copyright © 2017年 yuansui. All rights reserved.
//

import Foundation

public enum NetworkMethod {
    case Get
    case Post
    case Upload
    case Download // TODO: 下载暂不实现
}

open class NetworkReq {
    var url: String?;
    var params: Dictionary<String, String>?;
    var fileParams: Dictionary<String, String>?;
    var streamParams: Dictionary<String, Stream>?;
    var fileArrs: Array<Any>?;
    var streamArrs: Array<Any>?
    
    var destination: String?;

    var headers: Dictionary<String, String>?;

    var method: NetworkMethod = .Get;

    public static func newBuilder(_ url: String) -> NetworkReqBuilder {
        return NetworkReqBuilder(url);
    }
}

open class NetworkReqBuilder {

    var url: String?;
    var destination: String?;

    lazy var params: Dictionary = {
        return Dictionary<String, String>();
    }();

    lazy var fileParams: Dictionary = {
        return Dictionary<String, String>();
    }();

    lazy var streamParams: Dictionary = {
        return Dictionary<String, Stream>();
    }();

    lazy var headers: Dictionary = {
        
        return Dictionary<String, String>();
    }();
    
    lazy var fileArrs: Array = {
        return Array<Any>();
    }();
    
    lazy var streamArrs: Array = {
        return Array<Any>();
    }();

    var method: NetworkMethod = .Get;

    init(_ url: String) {
        self.url = url;
    }

    public func get() -> Self {
        method = .Get;
        return self;
    }

    public func post() -> Self {
        method = .Post;
        return self;
    }

    public func upload() -> Self {
        method = .Upload;
        return self;
    }
    
    public func uploadFileArrs(_ arr: Array<Any>) -> Self {
        fileArrs = arr;
        return self;
    }
    
    public func uploadFile(_ file: Data) -> Self {
        fileArrs.append(file)
        return self;
    }
    
    public func download() -> Self {
        method = .Download;
        return self;
    }
    
    public func dest(_ dest: String) -> Self {
        destination = dest;
        return self;
    }

    public func param(_ name: String, _ val: String) -> Self {
        guard !TextUtil.isEmpty(val) else {
            return self;
        }
        
        params.updateValue(val, forKey: name);
        return self;
    }
    
//    public func model(_ m:T) -> Self {
//        networkModel = m;
//        return self;
//    }

    public func param(_ name: String, _ val: Int) -> Self {
        params.updateValue(String(val), forKey: name);
        return self;
    }

    public func param(_ name: String, _ val: Double) -> Self {
        params.updateValue(String(val), forKey: name);
        return self;
    }

    public func param(_ pairs: Array<CommonPair>) -> Self {
        var pairs = pairs;
        for p in pairs {
            pairs.append(p);
        }

        return self;
    }

    public func param(_ name: String, _ val: Stream) -> Self {
        streamParams.updateValue(val, forKey: name);
        return self;
    }

    public func paramFile(_ name: String, _ path: String) -> Self {
        fileParams.updateValue(path, forKey: name);
        return self;
    }

    public func header(_ name: String, _ val: String) -> Self {
        headers.updateValue(val, forKey: name);
        return self;
    }

    public func header(_ name: String, _ val: Int) -> Self {
        return header(name, String(val));
    }

    public func header(_ headers: Dictionary<String, String>) -> Self {
        for h in headers {
            self.headers.updateValue(h.value, forKey: h.key);
        }
        return self;
    }

    open func build() -> NetworkReq {
        let req = NetworkReq ();

        req.url = url;
       
        req.method = method;
        
        req.params = params;
        req.fileParams = fileParams;
        req.streamParams = streamParams;

        req.headers = headers;
        req.destination = destination;
        req.fileArrs = fileArrs;
        req.streamArrs = streamArrs;
        return req;
    }

}








